home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / graphics / gifmach0 / part01 / Sources / giftosham.c < prev    next >
C/C++ Source or Header  |  1991-02-07  |  5KB  |  227 lines

  1. /* Copyright 1990 by Christopher A. Wichura.
  2.    See file GIFMachine.doc for full description of rights.
  3. */
  4.  
  5. #include "GIFMachine.h"
  6.  
  7. extern struct GIFdescriptor gdesc;
  8. EXTERNBITPLANE;
  9.  
  10. extern char *AbortMsg;
  11.  
  12. extern BOOL Laced;
  13.  
  14. UWORD *SHAMmem;
  15.  
  16. struct RGB Palette[16];
  17.  
  18. extern UBYTE PaletteBuf[MAXCOLOURS];
  19. extern ULONG ColourBuf[MAXCOLOURS];
  20. static ULONG ErrBuf[MAXCOLOURS];
  21.  
  22. #define ISLACED (Laced && (y != gdesc.gd_Height - 1))
  23.  
  24. void GIFtoSHAM(void)
  25. {
  26.     register UWORD x;
  27.     register UWORD current;
  28.     register int index;
  29.     register int index2;
  30.     ULONG error;
  31.     UWORD y;
  32.     int Pal;
  33.     int ShamIndex;
  34.     int colours;
  35.  
  36.     ULONG TotalErr, LineErr;
  37.  
  38.     ULONG bestpal;
  39.     ULONG besterr;
  40.  
  41.     UBYTE CurrentRed,  CurrentGreen,  CurrentBlue;
  42.     UBYTE PreviousRed, PreviousGreen, PreviousBlue;
  43.  
  44.     MyPrintf("...Converting to SHAM format.\n......Line");
  45.  
  46.     ShamIndex = TotalErr = 0;
  47.  
  48.     /* palette zero is always the background colour.  regardless of
  49.        what the GIF specified for the background, we always use black.
  50.        this is a kludge to get around a hardware `feature' that causes
  51.        all overscanned screens to have a black background regardless
  52.        of what the background was specified to be.
  53.     */
  54.  
  55.     Palette[0].rgb_Red = Palette[0].rgb_Green = Palette[0].rgb_Blue = 0;
  56.  
  57.     for (y = 0; y < gdesc.gd_Height; y += (ISLACED ? 2 : 1)) {
  58.         if (ISLACED)
  59.             MyPrintf("s %5ld-%5ld", y, y + 1);
  60.         else
  61.             MyPrintf(" %5ld", y);
  62.  
  63.         if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  64.             MyPrintf("\n%s", AbortMsg);
  65.             MyExit(ABORTEXITVAL);
  66.         }
  67.  
  68.         memset((char *)ColourBuf, 0, sizeof(ColourBuf));
  69.  
  70.         for (colours = index2 = 0; index2 < (ISLACED ? 2 : 1); index2++)
  71.             for (x = 0; x < gdesc.gd_Width; x++) {
  72.                 current = GetValue(x, y + index2);
  73.  
  74.                 if (ColourBuf[current]++ == 0)
  75.                     colours++;
  76.             }
  77.  
  78.         MyPrintf(", %4ld unique colours", colours);
  79.  
  80.         memset((char *)PaletteBuf, 0, sizeof(PaletteBuf));
  81.  
  82.         for (index = 0; index < MAXCOLOURS; index++) {
  83.             if (ColourBuf[index] == 0)
  84.                 continue;
  85.  
  86.             ErrBuf[index] = RGBdiff(GetRed(index),
  87.                         GetGreen(index),
  88.                         GetBlue(index),
  89.                         Palette[0].rgb_Red,
  90.                         Palette[0].rgb_Green,
  91.                         Palette[0].rgb_Blue);
  92.         }
  93.  
  94.         for (Pal = 1; Pal < 16; Pal++) {
  95.             for (besterr = index = 0; index < MAXCOLOURS; index++) {
  96.                 if (ColourBuf[index] == 0)
  97.                     continue;
  98.  
  99.                 if (ErrBuf[index] * ColourBuf[index] >= besterr) {
  100.                     bestpal = index;
  101.                     besterr = ErrBuf[index] * ColourBuf[index];
  102.                 }
  103.             }
  104.  
  105.             Palette[Pal].rgb_Red   = GetRed(bestpal);
  106.             Palette[Pal].rgb_Green = GetGreen(bestpal);
  107.             Palette[Pal].rgb_Blue  = GetBlue(bestpal);
  108.  
  109.             for (index = 0; index < MAXCOLOURS; index++) {
  110.                 if (ColourBuf[index] == 0)
  111.                     continue;
  112.  
  113.                 error = RGBdiff(GetRed(index),
  114.                         GetGreen(index),
  115.                         GetBlue(index),
  116.                         Palette[Pal].rgb_Red,
  117.                         Palette[Pal].rgb_Green,
  118.                         Palette[Pal].rgb_Blue);
  119.  
  120.                 if (error < ErrBuf[index]) {
  121.                     ErrBuf[index] = error;
  122.                     PaletteBuf[index] = Pal;
  123.                 }
  124.             }
  125.         }
  126.  
  127.         for (index = 0; index < 16; index++)
  128.             SHAMmem[ShamIndex++] = (UWORD)(
  129.                 Palette[index].rgb_Red   << 8 |
  130.                 Palette[index].rgb_Green << 4 |
  131.                 Palette[index].rgb_Blue);
  132.  
  133.         for (index2 = 0; index2 < (ISLACED ? 2 : 1); index2++) {
  134.             PreviousRed   = Palette[0].rgb_Red;
  135.             PreviousGreen = Palette[0].rgb_Green;
  136.             PreviousBlue  = Palette[0].rgb_Blue;
  137.  
  138.             for (LineErr = x = 0; x < gdesc.gd_Width; x++) {
  139.                 current = GetValue(x, y + index2);
  140.  
  141.                 CurrentRed   = GetRed(current);
  142.                 CurrentGreen = GetGreen(current);
  143.                 CurrentBlue  = GetBlue(current);
  144.  
  145.                 besterr = ErrBuf[current];
  146.                 bestpal = PaletteBuf[current];
  147.  
  148.                 error = RGBdiff(
  149.                     CurrentRed,
  150.                     CurrentGreen,
  151.                     CurrentBlue,
  152.                     CurrentRed,
  153.                     PreviousGreen,
  154.                     PreviousBlue);
  155.  
  156.                 if (error < besterr) {
  157.                     besterr = error;
  158.                     bestpal = 16;
  159.                 }
  160.  
  161.                 error = RGBdiff(
  162.                     CurrentRed,
  163.                     CurrentGreen,
  164.                     CurrentBlue,
  165.                     PreviousRed,
  166.                     CurrentGreen,
  167.                     PreviousBlue);
  168.  
  169.                 if (error < besterr) {
  170.                     besterr = error;
  171.                     bestpal = 17;
  172.                 }
  173.  
  174.                 error = RGBdiff(
  175.                     CurrentRed,
  176.                     CurrentGreen,
  177.                     CurrentBlue,
  178.                     PreviousRed,
  179.                     PreviousGreen,
  180.                     CurrentBlue);
  181.  
  182.                 if (error < besterr) {
  183.                     besterr = error;
  184.                     bestpal = 18;
  185.                 }
  186.  
  187.                 if (bestpal < 16) {
  188.                     PutValue(x, y + index2, bestpal);
  189.  
  190.                     PreviousRed   = Palette[bestpal].rgb_Red;
  191.                     PreviousGreen = Palette[bestpal].rgb_Green;
  192.                     PreviousBlue  = Palette[bestpal].rgb_Blue;
  193.                 } else if (bestpal == 16) {
  194.                     PutValue(x, y + index2, CurrentRed | 0x20);
  195.  
  196.                     PreviousRed = CurrentRed;
  197.                 } else if (bestpal == 17) {
  198.                     PutValue(x, y + index2, CurrentGreen | 0x30);
  199.  
  200.                     PreviousGreen = CurrentGreen;
  201.                 } else {
  202.                     PutValue(x, y + index2, CurrentBlue | 0x10);
  203.  
  204.                     PreviousBlue = CurrentBlue;
  205.                 }
  206.  
  207.                 LineErr += besterr;
  208.             }
  209.  
  210.             TotalErr += LineErr;
  211.         }
  212.  
  213.         MyPrintf("\x9B" "%sD\x9BK", (ISLACED ? "34" : "27"));
  214.     }
  215.  
  216.     {
  217.         ULONG    ErrPerPixel;
  218.         char    TextBuf[10];
  219.  
  220.         ErrPerPixel = ((TotalErr / gdesc.gd_Height) * 1000) / gdesc.gd_Width;
  221.         MySPrintf(TextBuf, "%ld.%03ld", ErrPerPixel / 1000, ErrPerPixel % 1000);
  222.  
  223.         MyPrintf("\x9B" "4DTotal colour error = %ld, Mean per line = %ld, Per pixel = %s.\n",
  224.             TotalErr, TotalErr / gdesc.gd_Height, TextBuf);
  225.     }
  226. }
  227.